load("js/luajs/cgb_luaFunc.js")




var PATTERN_SHORT_MONTH = "yyyyMM";
var url = "https://ebanks.cgbchina.com.cn/perbank/";
var listC = new ArrayList();
var listD = new ArrayList();
var map = new HashMap();
var EMP_SID = null;
var card = 0;
var card_Id = 1;
var bill_ShoppingSheet_Id = 1;
var bill_ID = 1;
var checkTime = 0;

var  SESSIONDATA_URL = "https://ebanks.cgbchina.com.cn/perbank/sessionData.do";
var  USERINFO_URL = "https://ebanks.cgbchina.com.cn/perbank/ECAD0003.do";
var  CRTBILL_URL = "https://ebanks.cgbchina.com.cn/perbank/CR1001.do";
var  BILLMAIN_URL = "https://ebanks.cgbchina.com.cn/perbank/CR1080.do";
var  DETAIL_URL = "https://ebanks.cgbchina.com.cn/perbank/CR0002.do";
var  SELECTED_URL = "https://ebanks.cgbchina.com.cn/perbank/mvcAccess.do";

var isDebug = false;
var billId = 0;
/**
 * 储蓄卡的ID
 */
var chuxukaId = 0;

/**
 * 本期新增等于支出之和
 */
var new_change = 0;
/**
 * 还款日，当本期无需还款的时候计算还款日
 */
var day = "";
var checked = false;

var types = new LinkedHashMap();
{
    types.put("工资", "SALARY");
    types.put("奖金", "BONUS");
    types.put("利息", "ACCRUAL");
    types.put("存现", "DEPOSIT");
    types.put("转账", "TRANSFER");
    types.put("普通汇兑", "TRANSFER");
    types.put("借货", "LOANS");
    types.put("冲账", "REVERSE");
    types.put("退款", "REFUND");
    types.put("结息转入", "EARNINGS");
    types.put("收益", "EARNINGS");
    types.put("报销", "CLAIM");
    types.put("其它收入", "OTHERREVENUE");
    types.put("燃油补贴", "OTHERREVENUE");
    types.put("取现", "WITHDRAW");
    types.put("支取", "WITHDRAW");
    types.put("手续费", "HANDLINGFEE");
    types.put("转账", "TRANSFER");
    types.put("网银入账", "TRANSFER");
    types.put("网银转入", "TRANSFER");
    types.put("还贷", "REPAYMENT");
    types.put("理财", "FINANCE");
    types.put("活转定", "FINANCE");
    types.put("存款户现金存款", "FINANCE");
    types.put("翼支付", "CONSUMPTION");
    types.put("消费", "CONSUMPTION");
    types.put("消费", "CONSUMPTION");
    types.put("出金", "CONSUMPTION");
    types.put("快捷支付", "CONSUMPTION");
    types.put("房租", "RENT");
    types.put("公积金", "FUND");
    types.put("社保", "SOCIALSECURITY");
    types.put("通讯费", "COMMUNICATIONFEE");
    types.put("生活费", "LIVINGEXPENSE");
    types.put("其它费用", "OTHERFEE");
    types.put("其它支出", "OTHEREXPENSE");
}

var saveType = new LinkedHashMap();
{
    saveType.put("YSV", "活期");
    saveType.put("YTM", "整存整取");
    saveType.put("YNT", "通知存款");
    saveType.put("ATF", "丰收优利");
    saveType.put("YTD", "定活智能通");
}
var savePeroid = new LinkedHashMap();
{
    savePeroid.put("201", "1-MONTH");
    savePeroid.put("203", "3-MONTH");
    savePeroid.put("206", "6-MONTH");
    savePeroid.put("301", "1-YEAR");
    savePeroid.put("302", "2-YEAR");
    savePeroid.put("303", "3-YEAR");
    savePeroid.put("305", "5-YEAR");
    savePeroid.put("308", "8-YEAR");
    savePeroid.put("101", "1-DAY");
    savePeroid.put("107", "7-DAY");
    savePeroid.put("213", "13-MONTH");
    savePeroid.put("214", "14-MONTH");
    savePeroid.put("215", "15-MONTH");
    savePeroid.put("218", "18-MONTH");
    savePeroid.put("220", "20-MONTH");
    savePeroid.put("221", "21-MONTH");
    savePeroid.put("230", "30-MONTH");
}

var v4_cgb_java_funcs = {
    openHomePage : function(){
        //判断当前线程是否被锁，如果被锁，则等待锁释放
        logger.info("广发银行taskKey = {} 判断当前线程是否持有锁",context.get(Constants.LUA_TASK_KEY));
        var lockFlag = lock.isHeldByCurrentThread() ;
        if (lockFlag) {
            logger.info("广发银行taskKey = {} 当前线程已经持有锁，无需再次获取锁",context.get(Constants.LUA_TASK_KEY));
        }else {
            logger.info("广发银行taskKey = {} 当前线程没有持有锁，等待获取锁",context.get(Constants.LUA_TASK_KEY));
            lock.lock();
        }
        //广发银行官网首页
        var loginText = get(url);
        storeDataToFile(context, loginText, "firstLoginText.html");
        context.put("login_html",loginText);
    },
    checkProxyAvailable: function(){

        // 获取首页
        var html =context.get("login_html");
        if (html.contains("代理服务器没有响应") || html.contains("使用搜索引擎查找页面") || html.contains("无法显示此页")) {
            logger.info("广发银行taskKey = {} 代理IP异常", context.get(Constants.LUA_TASK_KEY));
            return false;
        }
        return true;
    },
    checkTargetWebsiteAvailable:function () {
        return true;
    },
    needResetEnvironment:function(){
        return true;
    },
    checkControlAvailable:function () {
        //检查控件是否加载成功，或者是否安装
        return Boolean.valueOf(checkControlAvailable());
    },
    login:function () {
        inputBase();
        inputImg();
    },
    crawl:function(){
        // 获取首页源码
        var indexPage = get_html();
        // 休眠是为了让网页渲染比较完全（全部渲染完需要很久，部分渲染是为了防止嵌入js报错）
        Thread.sleep(3000);
        storeDataToFile(context, indexPage, "indexPage.html")
        logger.info(BankCode.CGB + " 获取用户ID开始 taskkey {}",context.get(Constants.LUA_TASK_KEY));
        // 解析首页拿到 _emp_sid 拿不到直接返回
        var EMP_SID = parseEmpSid(indexPage);
        logger.info(BankCode.CGB + " 获取用户ID结束 taskkey {}",context.get(Constants.LUA_TASK_KEY));

        if (EMP_SID == null) {
            logger.error(BankCode.CGB + " 获取用户ID失败 taskkey {}",context.get(Constants.LUA_TASK_KEY));
            throw new BankException(BankConstants.BALO_99601_40, "获取用户ID失败");
        }
        map.put("EMP_SID", EMP_SID);
        logger.info("EMP_SID:" + EMP_SID+" taskkey {}",context.get(Constants.LUA_TASK_KEY));
        Thread.sleep(300);


        var paramsMap = new HashMap();
        paramsMap.put("EMP_SID", EMP_SID.trim());
        logger.info(BankCode.CGB + " 获取session开始 taskkey {}",context.get(Constants.LUA_TASK_KEY));
        //拼接需要请求的url
        var url = generateURL(SESSIONDATA_URL, paramsMap);
        var html = ajax_get(url);
        logger.info(BankCode.CGB + " 获取session结束 taskkey {}",context.get(Constants.LUA_TASK_KEY));
        storeDataToFile(context, html, "session" + ".html")
        Thread.sleep(5000);
        //获取卡的个数
        var length = get_card_size();
        logger.info(BankCode.CGB + "信用卡size="+length+" taskkey {}",context.get(Constants.LUA_TASK_KEY));
        var inObj = JSON.parseObject(html);
        var cd = inObj.getJSONObject("cd");
        //信息都存在Json的cd中，如果cd为空，则视为没有查询到客户信息
        if(cd==null){
            throw new BankException(BankConstants.BALO_22107_10, "没有查询到客户信息");
        }
        //从cd中取值
        var user_name = cd.getString("session_customerNameCN");// 姓名
        var user_mobile = cd.getString("session_mobileNo");// 真实手机号
        // String user_card = cd.getString("session_certNo");//
        var session_iAccountInfoArray = cd.getJSONArray("session_iAccountInfo");
        logger.info(BankCode.CGB+"获取卡数量:"+session_iAccountInfoArray.size()+" taskkey {} ",context.get(Constants.LUA_TASK_KEY));
        var map1 = new LinkedHashMap();
        for (var i = 0; i < session_iAccountInfoArray.size(); i++) {
            //一些计数变量++
            nextCard();
            var session_iAccountInfoObj = session_iAccountInfoArray.getJSONObject(i);
            //遍历所需的参数
            for each (var key in session_iAccountInfoObj.keySet()) {
                map1.put(key, session_iAccountInfoObj.getString(key));
            }
            map.putAll(map1);
            var accountType = session_iAccountInfoObj.getString("accountType");
            var accountNo = session_iAccountInfoObj.getString("accountNo");
            map.put("session_mobileNo", user_mobile);
            map.put("accountNo", accountNo);
            if (StringUtils.isNotBlank(accountType)) {
                // 30是信用卡
                if ("30".equals(accountType)) {
                    var iscountie = true;
                    //这里如果一张卡做过变更，可能会有两个卡号，如果是一张卡，卡信息和账单信息就抓完了，所以不在抓第二个卡号，并把卡号链接，已","隔开
                    for each (var entry in cardList.entrySet()) {
                        if(entry.getKey().length>1){
                            for each (var key in entry.getKey()) {
                                if(getLast4Str(accountNo).equals(key)){
                                    jointCardNo(entry.getValue(),accountNo);
                                    iscountie = false;
                                }
                            }
                        }
                    }
                    //如果不是一张卡则继续抓取
                    if(iscountie){
                        try {
                            logger.info(BankCode.CGB + "卡" + card + " 抓取信用卡开始 taskkey {}", context.get(Constants.LUA_TASK_KEY));
                            var card = crawlXinyongka(user_name, EMP_SID, map, map1);
                            logger.info(BankCode.CGB + "卡" + card + " 抓取信用卡结束 taskkey {}", context.get(Constants.LUA_TASK_KEY));
                            listC.add(card);
                        }catch(e){
                            statCaughtException(context, e);
                            logger.error(BankCode.CGB + "卡" + card + " 抓取信用卡异常 taskkey {}", context.get(Constants.LUA_TASK_KEY))
                        }
                    }
                }
                // 30是信用卡
                if (!"30".equals(accountType)) {
                    logger.info(BankCode.CGB + "卡" + card + " 抓取储蓄卡开始 taskkey {}",context.get(Constants.LUA_TASK_KEY));
                    try {
                        var card = crawlChuxuka(user_name, EMP_SID, map, map1);
                        logger.info(BankCode.CGB + "卡" + card + " 抓取储蓄卡结束 taskkey {}", context.get(Constants.LUA_TASK_KEY));
                        listD.add(card);
                    }catch (e){
                        statCaughtException(context, e);
                        logger.error(BankCode.CGB + "卡" + card + " 抓取借记卡异常 taskkey {}", context.get(Constants.LUA_TASK_KEY))
                    }
                }
            }
        }
        if (monthBill.size() > 0) {
            storeDataToFile(context, JSON.toJSONString(monthBill),  "monthBill.html");
        }
        context.put(Constants.CREDIT_DATA, listC);
        context.put(Constants.DEBIT_DATA, listD);

    },
    exitLogin :function () {},
    exit:function () {}
}


function inputBase(){
    //获取登录用户名
    var loginStr = getLoginParams(context)[0];
    var passWord = context.get(Constants.LUA_TASK_TOKEN);

    logger.info(BankCode.CGB + " 登录开始 taskkey {}",context.get(Constants.LUA_TASK_KEY));
    logger.info(BankCode.CGB + " 输入用户名开始 taskkey {}",context.get(Constants.LUA_TASK_KEY));
    // 输入用户,卡号
    set_input_text_by_id("loginId", loginStr);

    Thread.sleep(500);
    //展示页面
    show();
    // show_noff();
    logger.info(BankCode.CGB + " 输入密码开始 taskkey {}",context.get(Constants.LUA_TASK_KEY));
    //输入密码并返回密码全是*号表示
    var pwdCheckResult = input_password_callback(passWord);// 输入密码

    //检查密码是否正确输入

   var isCorrectFunc = function (inputPassword) {
       logger.info("inputPassword="+inputPassword);
       logger.info("inputPassword.length="+inputPassword.length);
       logger.info("passWord.length="+passWord.length);
        return inputPassword.length == passWord.length;
    };
    //输入完密码hide()隐藏窗口，因为多个任务同时只能打开一个ie
    hide();
    var getErrorMsg = function () {
        return "密码因控件输入错误";
    };
    assertTrueOrThrowException(pwdCheckResult, isCorrectFunc, getErrorMsg)
    logger.info(pwdCheckResult+" taskkey {}",context.get(Constants.LUA_TASK_KEY));
    Thread.sleep(500);
}
function inputImg() {
    logger.info(BankCode.CGB + " 截图开始 taskkey {}",context.get(Constants.LUA_TASK_KEY));
    //通过id截取验证码图片
    var captchaPath = get_image_by_id("verifyImg");// 截图
    logger.info("任务【 {} 】图片验证码路径【 {} 】", context.get(LUA_TASK_KEY), captchaPath)
    var isCaptchaPathCorrectFunc = function(captchaPath) {
        return captchaPath !== null && captchaPath !== undefined && captchaPath !== 'path fail'
    }

    var getCaptchaPathErrorMsgFunc = function(captchaPath) {
        return "图片验证码获取失败"
    }

    assertTrueOrThrowException(captchaPath, isCaptchaPathCorrectFunc, getCaptchaPathErrorMsgFunc)
    logger.info("任务【 {} 】图片验证码获取成功", context.get(LUA_TASK_KEY))
    context.put(TASK_IMG_PATH,captchaPath);
    context.put(TASK_IMG_REGEX,"[0-9a-zA-Z]{4}");
    //调用打码平台获取验证码值
    var code = waitImgCodeBySecondsByJs(context,60,true,3);
    logger.info(BankCode.CGB + " 人工打码开始 taskkey {},获取的验证是{}",context.get(Constants.LUA_TASK_KEY),code);
    //如果返回的code位数不够，不返回false 继续走之后会获取验证码错误返回false并刷新验证码
    if (StringUtils.isBlank(code) || code.length() != 4) {
        logger.info("打码位数不是四位，手动补齐 {}  taskkey {}", code,context.get(Constants.LUA_TASK_KEY));
       // code="1234";
    }
    logger.info(code);
    logger.info(BankCode.CGB + " 输入验证码开始 taskkey {}",context.get(Constants.LUA_TASK_KEY));
    //输入验证码
    set_input_text_by_id("captcha", code);// 输入验证码
    logger.info(BankCode.CGB + " 点击登录按钮开始 taskkey {}",context.get(Constants.LUA_TASK_KEY));
    //检查验证码是否输入正常
    var captchaInputResult = checkIfInput("captcha", code);

    var isCaptchaInputCorrectFunc = function(captchaInputResult) {
        return captchaInputResult
    }

    var getCaptchaInputErrorMsgFunc = function(captchaInputResult) {
        return "图片验证码输入错误"
    }
    assertTrueOrThrowException(captchaInputResult, isCaptchaInputCorrectFunc, getCaptchaInputErrorMsgFunc);
    //点击登录按钮
    clickById("loginButton");
    Thread.sleep(3000);
    var isLoginCorrectFunc = function () {
        logger.info(BankCode.CGB + " 登录验证开始 taskkey {}",context.get(Constants.LUA_TASK_KEY));
        var new_url = get_url();
        if(new_url.contains("welcome.do")){
            //登录成功后释放锁
            lock.unlock();
            logger.info(BankCode.CGB + " 登录跳转成功 taskkey {}",context.get(Constants.LUA_TASK_KEY));
            return true;
        }else{
            return false;
        }
    };
    var contentWillBeCheckedFunc = function () {
        return "";
    }
    var getLoginErrorMsg = function () {

        var alert = get_alert_msg();
        logger.info("BankCode.CGB  taskkey {},获取alert弹出信息{}",context.get(Constants.LUA_TASK_KEY),alert);
        if (StringUtils.isNotBlank(alert)) {
            logger.info(BankCode.CGB+"alert:"+alert+" taskkey {}",context.get(Constants.LUA_TASK_KEY));
        }
        //如果包含验证码，做重试
        if (alert.contains("验证码")) {
            logger.info(BankCode.CGB + " 验证码识别失败,taskkey {}",context.get(Constants.LUA_TASK_KEY));
            return "图片验证码错误";
        }

        //获取当前页面
        var new_url = get_url();
        logger.info(BankCode.CGB + "  taskkey {}，获取当前路径 {}",context.get(Constants.LUA_TASK_KEY),new_url);
        //根据获取到页面上的返回错误信息，判断是否有异常
        var backMsg = getAreaMsg();
        var msg = JSON.parse(backMsg).getString("msg");
        logger.info(BankCode.CGB + "  taskkey {}，获取当前提示信息 {}",context.get(Constants.LUA_TASK_KEY),msg)
        if("https://ebanks.cgbchina.com.cn/perbank/#".equals(new_url) && StringUtils.equals(msg,"false") && StringUtils.equals(alert,"") ){
                return "请输入合法的账号";
        }


        //var html = Jsoup.parse(FileUtils.readFileToString(new File("C:\\Users\\Administrator\\18061012CREDups7aJ33\\login_result.html")));
        //获取当前页面信息
        //增加加载时间
        Thread.sleep(1000);
        if (new_url.contains("OT00") && new_url.contains(".do")) {
            var screenShots = getScreenShots();
            logger.info("交易失败截图路径{}", screenShots);
            //打印错误信息
            var msg=getInnerHTML("errorMessage");
            logger.info("msg="+msg);
            if(StringUtils.isNotBlank(msg)){
                if(msg.contains("冻结")){return "用户已暂时冻结"}
                if(msg.contains("账号或密码错误")){ return "账号或密码错误，请输入正确的账号和取款密码"}
                if(msg.contains("登录名或密码错误")){ return "账号或密码错误，请输入正确的账号和取款密码"}
                if(msg.contains("您的网银会暂时冻结")){ return "用户已暂时冻结"}
                if(msg.contains("卡片不存在")){ return "卡片不存在"}
                if(msg.contains("密码错误次数超限")){ return "信用卡密码错误次数超限"}
                if(msg.contains("密码处理异常")){return "密码处理异常"}
                if(msg.contains("尚未设置提现密码")){return "尚未设置提现密码"}
                if(msg.contains("return is null")){return "系统繁忙，请稍候再试（登录前）";}
                //返回新匹配分支
                return msg;
            }else{
                return "系统繁忙，请稍候再试（登录前）";
            }
        } else {
            logger.info(new_url+" taskkey {}",context.get(Constants.LUA_TASK_KEY));
            if(html.contains("欢迎您进入我行个人网银，请设置您的登录信息")){
                return "欢迎您进入我行个人网银，请设置您的登录信息";
            }else if(html.contains("设置网银登录密码")){
                return "设置网银登录密码";
            }else if(html.contains("重置网银登录密码")){
                return "重置网银登录密码";
            }
        }

    }
    assertTrueOrThrowExceptionByTimes(contentWillBeCheckedFunc, isLoginCorrectFunc, getLoginErrorMsg,15)
}


function jointCardNo( cardAllData,  accountNo) {
    var cardno = cardAllData.getFullCardNum();
    var last4no = cardAllData.getCardNum();
    cardno = cardno+","+accountNo;
    last4no = last4no+","+getLast4Str(accountNo);
    cardAllData.setCardNum(last4no);
    cardAllData.setFullCardNum(cardno);
}

/**
 * 账单信息只需查询一次就能查询到
 */
var monthBill = new LinkedHashMap();
var cardList = new  HashMap();

/**
 * 抓取信用卡
 *
 * @param EMP_SID
 * @param map
 * @return
 * @throws InterruptedException
 * @throws ParseException
 */
function crawlXinyongka( user_name,  EMP_SID,  map,  jiaoyijiluPostMap) {
    var creditCardAllData = getCreditCardAllData();
    var bills = new ArrayList();
    creditCardAllData.setBills(bills);

    creditCardAllData.setCardId(UUID.randomUUID().toString());
    creditCardAllData.setNameOnCard(user_name);
    creditCardAllData.setBankName("广发银行");
    creditCardAllData.setCardType("信用卡");

    //解析当前账单，就是未出账单
    parseCurrentBill(EMP_SID, creditCardAllData, map, jiaoyijiluPostMap);
    logger.info(BankCode.CGB + "卡" + card + " 卡已出账单开始,taskkey {}",context.get(Constants.LUA_TASK_KEY));
    // 循环获取历史账单
    var billDate = "";
    var unDoneMonth = "";
    if(creditCardAllData.getBills().get(0)!=null){
        billDate = creditCardAllData.getBills().get(0).getBillDate();
        unDoneMonth = creditCardAllData.getBills().get(0).getBillMonth().replace("-", "");
    }
    // 获取当前月份
    var currentMonth = getYearMonthStr(billDate) ;
    // 循环取12个月
    var keys = null;
    for (var i = 0; i < 12; i++) {
        //月份String偏移，如输入"201411","yyyyMM",5 -->"201504"
        var month = monthStringAmount(currentMonth, PATTERN_SHORT_MONTH, -i);
        if(unDoneMonth.equals(month)){
            //广发官网查询账单月份最后一个已出账单和当前账单可能差一个月的原因，这里i++;
            i++;
            month = monthStringAmount(currentMonth, PATTERN_SHORT_MONTH, -i);
        }

        //解析账单概要
        var billmap = parseBillMain(EMP_SID, map, month);
        //如果map不等于null 直接放进去，如果为null 则根据卡号和账单日重新获取一个map
        if (billmap != null) {
            monthBill.put(month, billmap);
        }else{
            var billmap1 =getBillMap(month,creditCardAllData,map.get("accountNo"),billDate);
            monthBill.put(month, billmap1);
        }

        var billmap = monthBill.get(month);
        if(keys==null){
            for each (var string in billmap.keySet()) {
                keys = string;
            }

        }
        //遍历所抓取的没个月的数据，放到bills中
        if (billmap != null) {
            var accountNo = map.get("accountNo");
            var billData = null;
            for each (var billAllData in billmap.entrySet()) {
                for each(var str in billAllData.getKey()) {
                    if(accountNo.contains(str)){
                        billData = billAllData.getValue();
                    }
                }
            }
            if (billData != null) {
                bills.add(billData);
            }
        }
    }
    logger.info(BankCode.CGB + "卡" + card + " 卡已出账单结束,taskkey {}",context.get(Constants.LUA_TASK_KEY));
    var list = creditCardAllData.getBills();
    if (list != null && list.size() > 0) {
        for each (var billAllData in list) {
            //处理分期信息
            parserInstallment(billAllData);
        }
    }
    setLastBalance(creditCardAllData);
    //设置未出账单的newBalance
    setUndoneNewBalance(creditCardAllData.getBills().get(0));
    cardList.put(keys, creditCardAllData);
    return creditCardAllData;
}



function setUndoneNewBalance( billAllData) {
    var new_balance = billAllData.getLastBalance()==null?BigDecimal.ZERO:billAllData.getLastBalance();
    var shoppings =  billAllData.getShoppingSheets();
    if(shoppings!=null&&shoppings.size()>0){
        for each (var expense in shoppings) {
            new_balance = new_balance.add(expense.getAmountMoney());
        }
    }
    billAllData.setNewBalance(new_balance);

}

function setLastBalance( creditCardAllData) {
    if(creditCardAllData.getBills()!=null&&creditCardAllData.getBills().size()>1){
        var last_balance = creditCardAllData.getBills().get(1).getNewBalance();
        creditCardAllData.getBills().get(0).setLastBalance(last_balance);
    }
}

function getBillMap( month,  creditCardAllData,  accountno,  billDate) {
    var billMap = new LinkedHashMap();
    var accountnos = getLast4Str(accountno);
    var billAllData = getBillAllData();
    billAllData.setBillMonth(getYYYYMM(month));
    billAllData.setCashLimit(creditCardAllData.getCashLimit());
    billAllData.setCreditLimit(creditCardAllData.getCreditLimit());
    billAllData.setBillId(UUID.randomUUID().toString());
    billAllData.setBankName("广发银行");
    billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(getYYYYMMDD(month,billDate)));
    billAllData.setBillType("DONE");
    billMap.put(accountnos, billAllData);
    return billMap;
}

function getYYYYMM(date){
    var year = date.substring(0,4);
    var month = date.substring(4);
    return year+"-"+month;
}
function getYYYYMMDD( date, billDate){
    var year = date.substring(0,4);
    var month = date.substring(4);
    var cal = Calendar.getInstance();
    cal.setTime(billDate);
    var day = cal.get(Calendar.DAY_OF_MONTH)
    if(equals("02",month)&&day>28){
        day = "28"
    }
    if(String.valueOf(day).length == 1){
        day="0"+day;
    }
    return year+"-"+month+"-"+day;
}



/**
 * 抓取储蓄卡
 *
 * @param EMP_SID
 * @param map
 * @return
 * @throws InterruptedException
 */
function crawlChuxuka( user_name,  EMP_SID,  map, jiaoyijiluPostMap) {
    var creditCardAllData = getCreditCardAllData();
    var bills = new ArrayList();
    creditCardAllData.setBills(bills);

    // creditCardAllData.setFullCardNum(parameter.getCardNo());
    creditCardAllData.setCardId(UUID.randomUUID().toString());
    creditCardAllData.setNameOnCard(user_name);
    creditCardAllData.setBankName("广发银行");
    creditCardAllData.setCardType("借记卡");
    var accountNo = map.get("accountNo");
    creditCardAllData.setFullCardNum(accountNo);
    creditCardAllData.setCardNum(accountNo.substring(accountNo.length() - 4));
    creditCardAllData.setOpenBank(jiaoyijiluPostMap.get("openNodeName"));

    crawlerChuXuKaBusiness(EMP_SID, map, creditCardAllData);
    // 获取用户基本信息
    // p.parseUserInfo( EMP_SID, creditCardAllData);

    return creditCardAllData;
}

function getYearMonthStr(billDate) {
    var cal = Calendar.getInstance();
    var day = cal.get(Calendar.DAY_OF_MONTH);
    var date = "";
    if(billDate!=null){
        cal.setTime(billDate)
        billDate = cal.get(Calendar.DAY_OF_MONTH);
        if(day<billDate){
            cal.setTime(new Date());
            cal.add(Calendar.MONTH,-1);
            date = DateFormatUtils.format(cal.getTime(), PATTERN_SHORT_MONTH);
        }else{
            date = DateFormatUtils.format(new Date(), PATTERN_SHORT_MONTH);
        }
    }else{
        date = DateFormatUtils.format(new Date(), PATTERN_SHORT_MONTH);
    }
    return date;
}

// 月份String偏移，如输入"201411","yyyyMM",5 -->"201504"
function monthStringAmount( monthStr,  format,  amount){
    // String转date
    var arr = new String(format);
    // arr.add(format);
    var date = DateUtils.parseDate(monthStr,arr);

    // date偏移
    date = DateUtils.addMonths(date, amount);

    // date转String
    return DateFormatUtils.format(date, format);
}

/**
 * 解析首页拿到 _emp_sid
 *
 * @param html
 * @return
 */
function parseEmpSid( html) {
    var _emp_sidStr = getLineFromHtml("_emp_sid", html);
    if (_emp_sidStr == null) {
        return null;
    }
    var temp = _emp_sidStr.split("'");
    if (temp.length == 3) {
        return temp[1];
    }

    return null;
}

// 从html中找到指定的变量所在的最近一行
function getLineFromHtml( targetStr,  htmlStr) {
    if (StringUtils.isBlank(htmlStr)) {
        return null;
    }
    var arrays = htmlStr.split("\n");
    for each (var str in arrays) {
        if (str.contains(targetStr)) {
            return str;
        }
    }
    return null;
}


/**
 * 解析保存在session里面的数据
 *
 * @param EMP_SID
 * @param creditcard
 * @param map
 * @return
 */
function parseSessionData( EMP_SID, creditcard, map) {
    var paramsMap = new HashMap();
    paramsMap.put("EMP_SID", EMP_SID.trim());
    var url = generateURL(SESSIONDATA_URL, paramsMap);
    var html = ajax_get(url);
    storeDataToFile(context, html,  "session");
    // logger.info("html:" + html);

    var inObj = JSON.parseObject(html);
    var cd = inObj.getJSONObject("cd");
    var user_name = cd.getString("session_customerNameCN");// 姓名
    var user_mobile = cd.getString("session_mobileNo");// 真实手机号
    var user_card = cd.getString("session_certNo");//
    creditcard.setFullCardNum(user_card);
    creditcard.setNameOnCard(user_name);
    var session_iAccountInfoArray = cd.getJSONArray("session_iAccountInfo");
    var map1 = new LinkedHashMap();
    for (var i = 0; i < session_iAccountInfoArray.size();) {
        var session_iAccountInfoObj = session_iAccountInfoArray.getJSONObject(i);
        for each (var key in session_iAccountInfoObj.keySet()) {
            map1.put(key, session_iAccountInfoObj.getString(key));
        }
        map.putAll(map1);
        var accountNo = session_iAccountInfoObj.getString("accountNo");
        map.put("accountNo", accountNo);
        break;
    }
    map.put("session_mobileNo", user_mobile);
    return map1;
}

/**
 * 解析当前账单，账单周期等信息<br>
 * 一般还款日是在账单日的20天之后<br>
 * 账单日之后的消费都算在下期账单
 *
 * @param EMP_SID
 * @param creditcard
 * @param map
 * @param jiaoyijiluPostMap
 */
function parseCurrentBill( EMP_SID, creditcard, map, jiaoyijiluPostMap) {
    var paramsMap = new HashMap();
    paramsMap.put("EMP_SID", EMP_SID.trim());
    paramsMap.put("accountNo", map.get("accountNo"));
    paramsMap.put("submitTimestamp", DateFormatUtils.format(new Date(), "yyyyMMddHHmmss"));
    paramsMap.put("trxCode", "b010101");
    var url = generateURL(CRTBILL_URL, paramsMap);
    logger.info(BankCode.CGB + "卡" + card + " 卡信息开始,taskkey {}",context.get(Constants.LUA_TASK_KEY));
    var jsonStr = ajax_get(url);
    storeDataToFile(context, jsonStr,  card+"_card_"+(card_Id++)+".html");

    var inObj = JSON.parseObject(jsonStr);
    if(inObj==null){
        logger.info(BankCode.CGB + "ajax_get返回为null,taskkey {}",context.get(Constants.LUA_TASK_KEY));
        throw new BankException(BankConstants.BACR_99602_20,"会话超时，请重新登录!");
    }else {
        //请求返回的Json中，em为错误信息，如果em不为空，则获取到并做异常处理
        if (inObj.getString("em").contains("会话已超时，请重新登录")) {
            logger.info(BankCode.CGB + "会话超时请重新登录,taskkey {}", context.get(Constants.LUA_TASK_KEY));
            throw new BankException(BankConstants.BACR_99602_20, "会话超时，请重新登录!");
        } else if (inObj.getString("em").contains("抱歉！由于网络原因，未收到执行结果")) {
            logger.info(BankCode.CGB + "由于网络原因，未收到执行结果,taskkey {}", context.get(Constants.LUA_TASK_KEY));
            throw new BankException(BankConstants.BALO_21301_10, "网络原因，系统繁忙");
        } else if(inObj.getString("em") == null || inObj.getString("em") == ""){
            //返回的Json中cd为卡信息，获取到卡信息继续解析
            var cd = inObj.getJSONObject("cd");
            //获取到部分卡信息
            var accountNo = cd.getString("accountNo");// 卡号
            creditcard.setFullCardNum(accountNo);
            creditcard.setCardNum(accountNo.substring(accountNo.length() - 4));
            var billDate = cd.getString("billDate");// 本期账单日
            var currentRtLmtDate = cd.getString("currentRtLmtDate");// 到期还款日

            var alldata = getBillAllData();
            alldata.setBillId(UUID.randomUUID().toString());
            alldata.setBillType("UNDONE");
            alldata.setBankName("广发银行");
            // 这里得到的账单日是本期的，但是未出的要+1
            var billdate = new Date(MyDateUtil.convergeTime(billDate));
            var c = Calendar.getInstance();
            c.setTime(billdate);
            c.add(Calendar.MONTH, 1);
            // 账单YEAR份为账单日
            alldata.setBillMonth(TimeUtil.getTimeStr(c.getTime(), "yyyy-MM"));
            alldata.setBillDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(c.getTime(), "yyyy-MM-dd")));
            var paymentDate = Calendar.getInstance();
            if (StringUtils.isNotBlank(currentRtLmtDate) && currentRtLmtDate.length() > 2) {
                day = currentRtLmtDate.substring(currentRtLmtDate.length() - 2);
            }
            paymentDate.setTimeInMillis(MyDateUtil.convergeTime(currentRtLmtDate));
            paymentDate.add(Calendar.MONTH, 1);
            alldata.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(paymentDate.getTime(), "yyyy-MM-dd")));
            logger.info(BankCode.CGB + "卡" + card + " 卡信息成功,taskkey {}", context.get(Constants.LUA_TASK_KEY));
            new_change = 0;// 抓取未出账单开始前，将本期新增的设置为0
            map.put("billDate", billDate);
            logger.info("本期账单日 :billDate = " + billDate + " taskkey {}", context.get(Constants.LUA_TASK_KEY));
            // 不同货币消费额度
            var iCreditCardListArray = cd.getJSONArray("iCreditCardList");
            for (var i = 0; i < iCreditCardListArray.size(); i++) {
                var iCreditCardList = iCreditCardListArray.getJSONObject(i);

                var creditLimitForCard = iCreditCardList.getString("creditLimitForCard");// 卡消费额度
                var cashLimitForCard = iCreditCardList.getString("cashLimitForCard");// 卡现金额度
                var cashAvailableLimit = iCreditCardList.getString("cashAvailableLimit");// 当前可用现金余额
                var balanceAvailable = iCreditCardList.getString("balanceAvailable");// 可用余额
                var currentRtLmtAmt = iCreditCardList.getString("currentRtLmtAmt");// 本期还款额
                var lastRtnLmtAmt = iCreditCardList.getString("lastRtnLmtAmt");// 本期最低还款额
                // String creditLimit = iCreditCardList.getString("creditLimit");//
                // 信用额度
                var currencyType = iCreditCardList.getString("currencyType");// 货币类型
                if (currencyType.equals("156")) {
                    logger.info(BankCode.CGB + "卡" + card + " 卡人民币信息开始,taskkey {}", context.get(Constants.LUA_TASK_KEY));
                    alldata.setNewBalance(GetJiner(currentRtLmtAmt));
                    //alldata.setMinPayment(GetJiner(lastRtnLmtAmt));
                    alldata.setCreditLimit(GetJiner(creditLimitForCard));
                    alldata.setCashLimit(GetJiner(cashLimitForCard));
                    creditcard.setCreditLimit(GetJiner(creditLimitForCard));
                    creditcard.setCashLimit(GetJiner(cashLimitForCard));
                    // 如果可用额度大于额度，设置为实际，否则设置为最大
                    if (GetJiner(balanceAvailable).doubleValue() <= GetJiner(creditLimitForCard).doubleValue()) {
                        creditcard.setBalance(GetJiner(balanceAvailable));
                    } else {
                        creditcard.setBalance(GetJiner(creditLimitForCard));
                    }
                    // 如果可用现金额度大于现金额度，设置为实际，否则设置为最大
                    if (GetJiner(cashAvailableLimit).doubleValue() <= GetJiner(cashLimitForCard).doubleValue()) {
                        creditcard.setCashBalance(GetJiner(cashAvailableLimit));
                    } else {
                        creditcard.setCashBalance(GetJiner(cashLimitForCard));
                    }
                    jiaoyijiluPostMap.put("currencyType", "156");
                    jiaoyijiluPostMap.put("index", "1");
                    jiaoyijiluPostMap.put("beginDate", billDate);
                    jiaoyijiluPostMap.put("endDate", TimeUtil.getTimeStr(new Date(), "yyyyMMdd"));
                    jiaoyijiluPostMap.put("cardNo", accountNo);
                    jiaoyijiluPostMap.put("turnPageBeginPos", "1");
                    jiaoyijiluPostMap.put("turnPageShowNum", "10");
                    jiaoyijiluPostMap.put("bigAccountSrcSign", "0");
                    jiaoyijiluPostMap.put("turnPageBeginPage", "1");
                    jiaoyijiluPostMap.put("EMP_SID", EMP_SID);
                    var bills = new ArrayList();
                    // jiaoyijiluPostMap.put("turnPageFlag", "2");
                    try {// 处理今天的
                        logger.info(BankCode.CGB + "卡" + card + " 卡当天交易记录开始,taskkey {}", context.get(Constants.LUA_TASK_KEY));
                        var postdata = new LinkedHashMap();
                        // submitTimestamp=20170531184249554
                        postdata.put("accountNo", jiaoyijiluPostMap.get("accountNo"));
                        postdata.put("EMP_SID", EMP_SID);
                        postdata.put("submitTimestamp", TimeUtil.getTimeStr(new Date(), "yyyyMMddHHmmssSSS"));
                        postdata.put("trxCode", "b080103");
                        var html = ajax_post("https://ebanks.cgbchina.com.cn/perbank/CR0132.do", jiaoyijiluPostMap);
                        storeDataToFile(context, html, card + "_bill_ShoppingSheet_Id_" + (bill_ShoppingSheet_Id++) + ".html");
                        //解析未出账单
                        parserUnDoBills(html, bills);
                        logger.info(BankCode.CGB + "卡" + card + " 卡当天交易记录结束,taskkey {}", context.get(Constants.LUA_TASK_KEY));
                    } catch (e) {
                        statCaughtException(context, e);
                        logger.error(e);
                    }

                    logger.info(BankCode.CGB + "卡" + card + " 卡本期未出账单开始,taskkey {}", context.get(Constants.LUA_TASK_KEY));
                    var html = ajax_post("https://ebanks.cgbchina.com.cn/perbank/CR0002.do", jiaoyijiluPostMap);
                    storeDataToFile(context, html, card + "_bill_ShoppingSheet_Id_" + (bill_ShoppingSheet_Id++) + ".html");
                    //解析已出账单，处理分页
                    var turnPageTotalNum = parserUnDoBills(html, bills);
                    for (var j = 11; j <= turnPageTotalNum; j += 10) {
                        jiaoyijiluPostMap.put("turnPageBeginPos", String.valueOf(j));
                        var currentPage = j / 10 + 1;
                        jiaoyijiluPostMap.put("turnPageBeginPage", String.valueOf(currentPage));
                        html = ajax_post("https://ebanks.cgbchina.com.cn/perbank/CR0002.do", jiaoyijiluPostMap);
                        storeDataToFile(context, html, card + "_bill_ShoppingSheet_Id_" + (bill_ShoppingSheet_Id++) + ".html");
                        parserUnDoBills(html, bills);
                    }
                    logger.info(BankCode.CGB + "卡" + card + " 卡本期未出账单结束,taskkey {}", context.get(Constants.LUA_TASK_KEY));
                    alldata.setShoppingSheets(bills);
                    logger.info(BankCode.CGB + "卡" + card + " 卡人民币信息成功,taskkey {}", context.get(Constants.LUA_TASK_KEY));
                } else if (currencyType.equals("840")) {
                    logger.info(BankCode.CGB + "卡" + card + " 卡美元信息成功,taskkey{}", context.get(Constants.LUA_TASK_KEY));
                    alldata.setUsdNewBalance(GetJiner(currentRtLmtAmt));
                    alldata.setUsdMinPayment(GetJiner(lastRtnLmtAmt));
                    alldata.setUsdCreditLimit(GetJiner(creditLimitForCard));
                    alldata.setUsdCashLimit(GetJiner(cashLimitForCard));
                    logger.info(BankCode.CGB + "卡" + card + " 卡美元信息结束,taskkey{}", context.get(Constants.LUA_TASK_KEY));
                } else {
                    logger.info("广发银行有其他币种，需要注意 卡号 ： {}", accountNo + ",taskkey {}", context.get(Constants.LUA_TASK_KEY));
                }
            }
            alldata.setNewCharges(GetJiner(String.valueOf(new_change)));
            var bills = creditcard.getBills();
            if (bills != null) {
                bills.add(alldata);
            }
            return alldata;
        }else{
            logger.info(BankCode.CGB + "新分支,taskkey {}，inObj = {}", context.get(Constants.LUA_TASK_KEY), inObj);
            throw new BankException(BankConstants.BACR_99601_60, "未知问题待查。")
        }

    }
}



/**
 * 解析账单概要
 *
 * @param EMP_SID
 * @param map
 * @param month
 * @return
 * @throws InterruptedException
 */
function parseBillMain(EMP_SID,  map,  month) {
    var paramsMap = new HashMap();
    paramsMap.put("currencyType", "");
    paramsMap.put("creditCardNo", map.get("accountNo"));
    paramsMap.put("billDate", month);
    paramsMap.put("billType", "1");
    paramsMap.put("abundantFlag", "0");
    paramsMap.put("terseFlag", "0");
    paramsMap.put("showWarFlag", "0");
    paramsMap.put("EMP_SID", EMP_SID.trim());
    var url = generateURL(BILLMAIN_URL, paramsMap);
    var jsonStr ="";
    for(var i=0;i<5;i++){
        jsonStr = ajax_get(url);
        if(jsonStr.contains("账单系统出现异常，请稍后再查询")){
            Thread.sleep(1000);
            continue;
        }else{
            break;
        }
    }
    storeDataToFile(context, jsonStr, card+"_credit_bill_list_"+(bill_ID++)+".html");
    // logger.info("html:" + jsonStr);

    return parserBills3(map, jsonStr);
}

function parserUnDoBills( html,  bills) {
    var turnPageTotalNum = 0;
    if (StringUtils.isNotBlank(html)) {
        var map = JSON.parseObject(html);
        if (map != null) {

            var cd =  map.get("cd");
            if (cd != null) {
                var total =  cd.get("turnPageTotalNum");
                if (StringUtils.isNotBlank(total) && total.matches("\\d{1,}")) {
                    turnPageTotalNum = Integer.valueOf(total);
                }
                var credResult =  cd.get("credResult");
                var card_num = getLast4Str(cd.get("accountNo")==null? cd.get("cardNo"): cd.get("accountNo"));
                if (credResult != null) {
                    for each (var map2 in credResult) {
                        var jiaoyiri =  map2.get("transferDate");
                        var ruzhangri = map2.get("recordDate");
                        var zhaiyao = map2.get("noteCode");
                        if (StringUtils.isNotBlank(zhaiyao)) {
                            zhaiyao = zhaiyao.trim();
                        } else {
                            zhaiyao = "";
                        }
                        var jiaoyijiner =  map2.get("transamt");
                        var jiaoyihuobi =  map2.get("currency");
                        if (jiaoyihuobi != null && jiaoyihuobi.equals("156")) {
                            jiaoyihuobi = "人民币";
                        }
                        card_num =  map2.get("last4OfCardNo");
                        var debitCreditCode =  map2.get("debitCreditCode");
                        if (!debitCreditCode.contains("-")) {
                            jiaoyijiner = "-" + jiaoyijiner;
                        } else {// 本期新增等于支出之和
                            new_change = new_change + GetJiner(jiaoyijiner).doubleValue();
                        }
                        var ruzhangjiner = jiaoyijiner;
                        if (StringUtils.isBlank(jiaoyiri) || !jiaoyiri.matches("\\d{4}\\d{2}\\d{2}")) {
                            continue;
                        }

                        var billdatail = createExpense(++billId, card_num, jiaoyiri, zhaiyao, jiaoyihuobi, jiaoyijiner, ruzhangri,
                            ruzhangjiner);
                        bills.add(billdatail);
                    }
                } else {
                    credResult =  cd.get("iTodayDetailList");

                    if (credResult != null) {
                        for each (var map2 in credResult) {
                            var jiaoyiri =  map2.get("tradeDate");
                            var ruzhangri =  map2.get("tradeDate");
                            var zhaiyao =  map2.get("merchantName");
                            var oldMerchantName = map2.get("oldMerchantName");
                            if (StringUtils.isNotBlank(zhaiyao)) {
                                zhaiyao = zhaiyao.trim();
                            } else {
                                zhaiyao = "";
                            }
                            var jiaoyijiner =  map2.get("transAmt");
                            var jiaoyihuobi =  map2.get("transCurr");
                            if (jiaoyihuobi != null && jiaoyihuobi.equals("156")) {
                                jiaoyihuobi = "人民币";
                            }
                            var transType =  map2.get("transType");
                            if (transType.contains("PY")) {
                                jiaoyijiner = "-" + jiaoyijiner;
                            } else {// 本期新增等于支出之和
                                new_change = new_change + GetJiner(jiaoyijiner).doubleValue();
                            }
                            var ruzhangjiner = jiaoyijiner;
                            if (StringUtils.isBlank(jiaoyiri) || !jiaoyiri.matches("\\d{4}\\d{2}\\d{2}")) {
                                continue;
                            }

                            var billdatail = createExpense(++billId, card_num, jiaoyiri, zhaiyao, jiaoyihuobi, jiaoyijiner, ruzhangri,
                                ruzhangjiner);
                            if (oldMerchantName != null) {
                                billdatail.setTransAddr(oldMerchantName);
                            }
                            bills.add(billdatail);
                        }
                    } else {
                        logger.error("解析未出账单失败,taskkey {}",context.get(Constants.LUA_TASK_KEY));
                    }
                }
            } else {
                logger.error("解析未出账单失败,taskkey {}",context.get(Constants.LUA_TASK_KEY));
            }
        } else {
            logger.error("解析未出账单失败,taskkey {}",context.get(Constants.LUA_TASK_KEY));
        }

    }
    return turnPageTotalNum;
}

/**
 * 从账单中挑出分期<br>
 * "shoppingsheet_id": "e91d7fe2-3aac-11e7-8406-00163e0dfac7",<br>
 * "trans_date": "2017-05-16 00:00:00",<br>
 * "post_date": "2017-05-16",<br>
 * "installment_type": "CONSUME",<br>
 * "total_month": 3,<br>
 * "current_month": 1,<br>
 * "currency_type": "CNY",<br>
 * "amount_money": 103.33,<br>
 * "installment_desc": "样样行消费分期17136070917"<br>
 *
 * @param creditBill
 */
function parserInstallment( creditBill) {
    if (creditBill != null && creditBill.getShoppingSheets() != null) {
        var list = creditBill.getShoppingSheets();
        var map = new LinkedHashMap();
        for each (var expense in list) {// 从交易记录中得到分期手续费那条记录
            var title = expense.getDescription();
            if (title != null && (title.contains("分期手续费")&&title.contains("/") || (title.contains("财智金")&&title.contains("手续费")&&title.contains("/")))) {
                var fenqiId = title.substring(title.indexOf("手续费") + 3).trim();
                var install = getInstallment();
                // (CONSUME-消费;CASH-现金;BILL-账单）
                if (title.contains("现金") || title.contains("财智金")) {// 根据标题，设置分期类型
                    install.setInstallmentType("CASH");
                } else if (title.contains("消费")) {
                    install.setInstallmentType("CONSUME");
                } else if (title.contains("账单")) {
                    install.setInstallmentType("BILL");
                } else {
                    logger.error("分期类型出现错误 ,{} ,taskkey {}", title,context.get(Constants.LUA_TASK_KEY));
                    install.setInstallmentType("BILL");
                }
                // 将手续费相关填到分期内容中
                logger.info("CGB---title: {} ,taskkey {}",title,context.get(Constants.LUA_TASK_KEY));
                var title1 = title.substring(0, title.indexOf("/"));
                title1 = title1.replace("手续费", "");
                install.setInstallmentDesc(title1);
                install.setHandingFee(expense.getAmountMoney());
                install.setCurrencyType("CNY");
                install.setPostDate(expense.getPostDate());
                install.setTransDate(expense.getTransDate());
                install.setHandingfeeDesc(title);
                var month = fenqiId.substring(fenqiId.indexOf("/") + 1);
                install.setCurrentMonth(Integer.valueOf(month));
                map.put(fenqiId, install);// 将分期id，和当前期放到map里
            }
        }
        for each (var expense in list) {
            var title = expense.getDescription();
            if (title != null && (title.contains("分期") || title.contains("财智金")) && !title.contains("冲账")) {
                for each (var string in map.keySet()) {
                    if(title.indexOf("手续费")>0&&title.indexOf("划账手续费")<0){
                        continue;
                    }
                    if (title.contains(string.substring(0,string.indexOf("/")-1))) {// 根据分期id和当前期，取到分期记录，然后填充
                        var install = map.get(string);
                        if(title.contains("划账手续费")){
                            install.setTransferFee(expense.getAmountMoney());
                            install.setTransferfeeDesc(title);
                        }else{
                            install.setAmountMoney(expense.getAmountMoney());
                            var total = title.substring(title.length() - 3, title.length() - 1);
                            install.setTotalMonth(Integer.valueOf(total));
                        }
                        install.setShoppingsheetId(expense.getId());
                    }
                }
            }
        }
        if (map.size() > 0) {
            creditBill.setInstallments(new ArrayList(map.values()));
        }
    }
}

/**
 * 通过网页解析账单
 *
 * @param map
 * @param jsonStr
 * @return
 */
function parserBills3_( map,  jsonStr) {

    var doc = Jsoup.parse(jsonStr);
    var billdate = null;
    var reportPanel4 = doc.select("#reportPanel4");
    var fixBand5 = doc.select("font");
    if (fixBand5.size() < 1) {
        logger.error(BankCode.CGB + " 账单周期解析不符规则 长度为 {},taskkey {}", fixBand5.size(),context.get(Constants.LUA_TASK_KEY));
        return null;
    }
    var startData = null;
    var endData = null;
    var infos = new LinkedHashMap();
    var BillDateflag = false;
    for (var i = 0; i < fixBand5.size(); i++) {
        var text = fixBand5.get(i).text();
        if (text.contains("账单周期")) {
            text = fixBand5.get(i + 1).text();
            var date = text.split("-");
            startData = date[0].replaceAll(" ", "").trim();
            endData = date[1].replaceAll(" ", "").trim();
            // creditBill.setBillDate(processDate(endData));
            billdate = new Date(MyDateUtil.convergeTime(endData));
            map.put("beginDate", startData);
            map.put("endDate", endData);
            BillDateflag = true;
            break;
        }
    }
    if (!BillDateflag) {// 没有解析到账单周期
        logger.error(BankCode.CGB + " 么有解析到账单周期,taskkey {}",context.get(Constants.LUA_TASK_KEY));
        return null;
    }
    var accountInfoFlag = false;
    var fixBand2 = reportPanel4.select("#groupFooter1").select("tr");
    if (fixBand2.size() > 0) {
        for each (var element in fixBand2) {

            var tds = element.select("td");
            if (tds.size() < 5) {
                continue;
            }
            var creditBill = getBillAllData();
            var cardNumber = tds.get(0).text().trim();
            // 上期账单金额
            var newBalance = tds.get(1).text().trim();
            // 上期还款金额
            var minPayment = tds.get(2).text().trim();
            var date = tds.get(3).text().trim();
            var currency = tds.get(4).text().trim();
            var creditLimit = tds.get(5).text().trim();
            creditBill.setBillDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(billdate, "yyyy-MM-dd")));
            creditBill.setBillMonth(TimeUtil.getTimeStr(billdate, "yyyy-MM"));
            creditBill.setBankName("广发银行");
            creditBill.setBillType("DONE");
            creditBill.setBillId(UUID.randomUUID().toString());
            if (currency.equals("人民币")) {
                creditBill.setNewBalance(GetJiner(newBalance));
                creditBill.setMinPayment(GetJiner(minPayment));
                if (date.contains("无需")) {// 如果显示无需还款，那么自己计算还款日
                    var c = Calendar.getInstance();
                    if (StringUtils.isNotBlank(day)) {// 广发银行的还款日一直是固定的值，按照账单月+还款日计算
                        var paymentDay = creditBill.getBillMonth() + "-" + day;
                        var paymentDayLong = MyDateUtil.convergeTime(paymentDay);
                        c.setTimeInMillis(paymentDayLong);
                        if (billdate.getTime() > paymentDayLong) {// 如果账单月+还款日后时间小于账单日，还款日月份+1
                            c.add(Calendar.MONTH, 1);
                        }
                    } else {// 如果没取到还款日，那么时间之能是错的了。。。
                        c.setTime(billdate);
                        c.add(Calendar.DATE, 25);
                        logger.error(BankCode.CGB + " 还款日靠猜 {},taskkey {}", currency,context.get(Constants.LUA_TASK_KEY));
                    }
                    creditBill.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(c.getTime(), "yyyy-MM-dd")));
                    var b = GetJiner(newBalance).multiply(new BigDecimal(-1));
                    creditBill.setNewBalance(b);
                } else {// 如果取到还款日，直接使用
                    var paydate = new Date(MyDateUtil.convergeTime(date));
                    creditBill.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(paydate, "yyyy-MM-dd")));
                }
                creditBill.setCreditLimit(GetJiner(creditLimit));
                creditBill.setCashLimit(creditBill.getCreditLimit().divide(new BigDecimal(2)));
            } else {

                creditBill.setUsdNewBalance(GetJiner(newBalance));
                creditBill.setUsdMinPayment(GetJiner(minPayment));
                if (date.contains("无需")) {// 如果显示无需还款，那么自己计算还款日
                    var c = Calendar.getInstance();
                    if (StringUtils.isNotBlank(day)) {// 广发银行的还款日一直是固定的值，按照账单月+还款日计算
                        var paymentDay = creditBill.getBillMonth() + "-" + day;
                        var paymentDayLong = MyDateUtil.convergeTime(paymentDay);
                        c.setTimeInMillis(paymentDayLong);
                        if (billdate.getTime() > paymentDayLong) {// 如果账单月+还款日后时间小于账单日，还款日月份+1
                            c.add(Calendar.MONTH, 1);
                        }
                    } else {// 如果没取到还款日，那么时间之能是错的了。。。
                        c.setTime(billdate);
                        c.add(Calendar.DATE, 25);
                        logger.error(BankCode.CGB + " 还款日靠猜 {},taskkey {}", currency,context.get(Constants.LUA_TASK_KEY));
                    }
                    creditBill.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(c.getTime(), "yyyy-MM-dd")));
                    var b = GetJiner(newBalance).multiply(new BigDecimal(-1));
                    creditBill.setUsdNewBalance(b);
                } else {// 如果取到还款日，直接使用
                    var paydate = new Date(MyDateUtil.convergeTime(date));
                    creditBill.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(paydate, "yyyy-MM-dd")));
                }
                creditBill.setUsdCreditLimit(GetJiner(creditLimit));
                creditBill.setUsdCashLimit(creditBill.getUsdCreditLimit().divide(new BigDecimal(2)));
                logger.error(BankCode.CGB + " 其他货币抓取靠猜 {},taskkey {}", currency,context.get(Constants.LUA_TASK_KEY));
            }
            var cardNumbers = cardNumber.trim().split(" ");
            var last4No ="";
            for each (var cardNo in cardNumbers) {
                if("".equals(last4No)){
                    last4No = getLast4Str(cardNo);
                }else{
                    last4No = last4No+"," + getLast4Str(cardNo);
                }
            }
            logger.info("任务taskKey = {}, last4No = {}", context.get(LUA_TASK_KEY), last4No);
            logger.info("任务taskKey = {}, last4No.split = {}", context.get(LUA_TASK_KEY), last4No.split);
            infos.put(last4No.split(","), creditBill);
            accountInfoFlag = true;

        }
    }

    if (!accountInfoFlag) {// 没有解析到账单周期
        logger.error(BankCode.CGB + " 么有解析到账户信息,taskkey {}",context.get(Constants.LUA_TASK_KEY));
        return null;
    }
    accountInfoFlag = false;
    var e = doc.select("#reportPanel5").select("#groupFooter1");
    if (e != null) {
        var trs = e.select("tr");
        for each (var element2 in trs) {
            var tds = element2.select("td");
            if (element2.text().contains("Card Number") || element2.text().contains("合  计") || tds.size() < 6) {
                continue;
            }
            var cardNumber = tds.get(0).text().trim();
            var	cardNumbers = cardNumber.split(" ");
            logger.info(BankCode.CGB + " 当前卡号" + cardNumber+",taskkey {}",context.get(Constants.LUA_TASK_KEY));
            var creditBill = null;
            for each (var billAllData in infos.entrySet()) {
                for each (var str in billAllData.getKey()) {
                    for each (var cardNo in cardNumbers) {
                        if(cardNo.contains(str)){
                            creditBill = billAllData.getValue();
                            break;
                        }
                    }
                }
            }
            if (creditBill == null) {
                logger.error(BankCode.CGB + " 详单解析出错,taskkey {}",context.get(Constants.LUA_TASK_KEY));
                return null;
            }
            var currency = tds.get(1).text().trim();
            // 上期账单金额
            var last_balance = tds.get(2).text().trim();
            // 上期还款金额
            var last_payment = tds.get(6).text().trim();
            last_payment = "-" + last_payment;
            // 本期新增款额
            var new_charges = tds.get(4).text().trim();
            if (new_charges.contains(" ")) {
                new_charges = new_charges.replace(" ", "+");
            }
            if (currency.equals("人民币")) {
                creditBill.setLastBalance(GetJiner(last_balance));
                //creditBill.setLastPayment(GetJiner(last_payment));
                creditBill.setNewCharges(GetJiner(new_charges));
            } else {
                creditBill.setUsdLastBalance(GetJiner(last_balance));
                //creditBill.setUsdLastPayment(GetJiner(last_payment));
                creditBill.setUsdNewCharges(GetJiner(new_charges));
                logger.error(BankCode.CGB + " 其他货币抓取靠猜 {},taskkey {}", currency,context.get(Constants.LUA_TASK_KEY));
            }
            accountInfoFlag = true;
        }
    }

    if (!accountInfoFlag) {// 没有解析到账单周期
        logger.error(BankCode.CGB + " 么有解析到本期应还信息,taskkey {}",context.get(Constants.LUA_TASK_KEY));
        return null;
    }
    var loopBand1 = doc.select("#loopBand1");
    if (loopBand1.size() >= 2) {
        logger.info(BankCode.CGB + " 和详单同级表格个数为 {},taskkey {}", loopBand1.size(),context.get(Constants.LUA_TASK_KEY));
        var loopBand2 = loopBand1.get(1).select("#loopBand2");
        if (loopBand2.size() == 0) {
            loopBand2 = loopBand1.get(0).select("#loopBand2");
        }
        for each (var element2 in loopBand2) {
            var cardNumber = element2.select("#groupHeader1").text();
            if (cardNumber.contains("（")) {
                cardNumber = cardNumber.substring(0, cardNumber.indexOf("（"));
            }
            logger.info(BankCode.CGB + " 当前卡号,taskkey {}" + cardNumber,context.get(Constants.LUA_TASK_KEY));
            var card_num = getLast4Str(cardNumber);
            var creditBill = null;
            for each (var billAllData in infos.entrySet()) {
                for each (var str in billAllData.getKey()) {
                    if(card_num.contains(str)){
                        creditBill = billAllData.getValue();
                    }
                }
            }
            var fixBand7 = element2.select("#fixBand7");
            var bills = new ArrayList();
            if(creditBill==null){
                return null;
            }
            creditBill.setShoppingSheets(bills);
            if (fixBand7.size() < 1) {
                logger.error(BankCode.CGB + " 账单解析不服规则 长度小于1 {},taskkey {}", fixBand7.size(),context.get(Constants.LUA_TASK_KEY));
                return null;
            }
            var trs1 = fixBand7.select("tr");
            var billId = 0;
            for each (var element3 in trs1) {
                if (element3.select("td").size() < 5) {
                    continue;
                }
                var jiaoyiri = element3.select("td").get(0).text();
                var ruzhangri = element3.select("td").get(1).text();
                var zhaiyao = element3.select("td").get(2).text();
                var jiaoyijiner = element3.select("td").get(3).text();
                var jiaoyihuobi = element3.select("td").get(4).text();
                var ruzhangjiner = element3.select("td").get(5).text();
                if (StringUtils.isBlank(jiaoyiri) || !jiaoyiri.matches("\\d{4}-\\d{2}-\\d{2}")) {
                    continue;
                }

                var billdatail = createExpense(++billId, card_num, jiaoyiri, zhaiyao, jiaoyihuobi, jiaoyijiner, ruzhangri, ruzhangjiner);
                bills.add(billdatail);
            }

            if (isDebug) {
                System.out.println(JSON.toJSON(creditBill));
            }
        }
    } else {
        logger.error(BankCode.CGB + " 详单解析出错,taskkey {}",context.get(Constants.LUA_TASK_KEY));
    }
    return infos;
}

/**
 * 通过网页解析账单
 *
 * @param map
 * @param jsonStr
 * @return
 */
function parserBills3( map,  jsonStr) {
    var doc = Jsoup.parse(jsonStr);
    var billdate = null;
    var fixBand5 = doc.select("#fixBand5");
    if (fixBand5.size() < 1) {
        logger.error(BankCode.CGB + " 账单周期解析不符规则 长度为 {},taskkey {}", fixBand5.size(),context.get(Constants.LUA_TASK_KEY));
        return null;
    }
    var startData = null;
    var endData = null;
    var infos = new LinkedHashMap();
    var BillDateflag = false;
    for each(var element in fixBand5) {
        var text = element.text();
        if (text.contains("账单周期")) {
            var billDate = element.select("td").get(2).text();
            var date = billDate.split("-");
            startData = date[0].replaceAll(" ", "").trim();
            endData = date[1].replaceAll(" ", "").trim();
            // creditBill.setBillDate(processDate(endData));
            billdate = new Date(MyDateUtil.convergeTime(endData));
            map.put("beginDate", startData);
            map.put("endDate", endData);
            BillDateflag = true;
            break;
        }
    }
    if (!BillDateflag) {// 没有解析到账单周期
        logger.error(BankCode.CGB + " 么有解析到账单周期,尝试下一解析方法,taskkey {}",context.get(Constants.LUA_TASK_KEY));
        return parserBills3_(map, jsonStr);// 一个卡两个账户的不能兼容,只能新增方法
    }
    var accountInfoFlag = false;
    var fixBand2 = doc.select("#fixBand2>table");
    if (fixBand2.size() > 0) {
        for each (var element in fixBand2) {
            var text = element.text();
            if (text.contains("信用卡账户信息") && text.contains("客户消费额度 Total Credit Limit")) {
                var trs = element.select("#fixBand7");
                for each (var element2 in trs) {
                    var tds = element2.select("td");
                    if (tds.size() < 5) {
                        continue;
                    }
                    var creditBill = getBillAllData();
                    var cardNumber = tds.get(0).text().trim();
                    // 上期账单金额
                    var newBalance = tds.get(1).text().trim();
                    // 上期还款金额
                    var minPayment = tds.get(2).text().trim();
                    var date = tds.get(3).text().trim();
                    var currency = tds.get(4).text().trim();
                    var creditLimit = tds.get(5).text().trim();
                    creditBill.setBillDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(billdate, "yyyy-MM-dd")));
                    creditBill.setBillMonth(TimeUtil.getTimeStr(billdate, "yyyy-MM"));
                    creditBill.setBankName("广发银行");
                    creditBill.setBillType("DONE");
                    creditBill.setBillId(UUID.randomUUID().toString());
                    if (currency.equals("人民币")) {
                        creditBill.setNewBalance(GetJiner(newBalance));
                        creditBill.setMinPayment(GetJiner(minPayment));
                        if (date.contains("无需")) {// 如果显示无需还款，那么自己计算还款日
                            var c = Calendar.getInstance();
                            if (StringUtils.isNotBlank(day)) {// 广发银行的还款日一直是固定的值，按照账单月+还款日计算
                                var paymentDay = creditBill.getBillMonth() + "-" + day;
                                var paymentDayLong = MyDateUtil.convergeTime(paymentDay);
                                c.setTimeInMillis(paymentDayLong);
                                if (billdate.getTime() > paymentDayLong) {// 如果账单月+还款日后时间小于账单日，还款日月份+1
                                    c.add(Calendar.MONTH, 1);
                                }
                            } else {// 如果没取到还款日，那么时间之能是错的了。。。
                                c.setTime(billdate);
                                c.add(Calendar.DATE, 25);
                                logger.error(BankCode.CGB + " 还款日靠猜 {},taskkey {}", currency,context.get(Constants.LUA_TASK_KEY));
                            }
                            creditBill.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(c.getTime(), "yyyy-MM-dd")));
                            var b = GetJiner(newBalance).multiply(new BigDecimal(-1));
                            creditBill.setNewBalance(b);
                        } else {// 如果取到还款日，直接使用
                            var paydate = new Date(MyDateUtil.convergeTime(date));
                            creditBill.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(paydate, "yyyy-MM-dd")));
                        }
                        creditBill.setCreditLimit(GetJiner(creditLimit));
                        creditBill.setCashLimit(creditBill.getCreditLimit().divide(new BigDecimal(2)));
                    } else {

                        creditBill.setUsdNewBalance(GetJiner(newBalance));
                        creditBill.setUsdMinPayment(GetJiner(minPayment));
                        if (date.contains("无需")) {// 如果显示无需还款，那么自己计算还款日
                            var c = Calendar.getInstance();
                            if (StringUtils.isNotBlank(day)) {// 广发银行的还款日一直是固定的值，按照账单月+还款日计算
                                var paymentDay = creditBill.getBillMonth() + "-" + day;
                                var paymentDayLong = MyDateUtil.convergeTime(paymentDay);
                                c.setTimeInMillis(paymentDayLong);
                                if (billdate.getTime() > paymentDayLong) {// 如果账单月+还款日后时间小于账单日，还款日月份+1
                                    c.add(Calendar.MONTH, 1);
                                }
                            } else {// 如果没取到还款日，那么时间之能是错的了。。。
                                c.setTime(billdate);
                                c.add(Calendar.DATE, 25);
                                logger.error(BankCode.CGB + " 还款日靠猜 {},taskkey {}", currency,context.get(Constants.LUA_TASK_KEY));
                            }
                            creditBill.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(c.getTime(), "yyyy-MM-dd")));
                            var b = GetJiner(newBalance).multiply(new BigDecimal(-1));
                            creditBill.setUsdNewBalance(b);
                        } else {// 如果取到还款日，直接使用
                            var paydate = new Date(MyDateUtil.convergeTime(date));
                            creditBill.setPaymentDueDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(paydate, "yyyy-MM-dd")));
                        }
                        creditBill.setUsdCreditLimit(GetJiner(creditLimit));
                        creditBill.setUsdCashLimit(creditBill.getUsdCreditLimit().divide(new BigDecimal(2)));
                        logger.error(BankCode.CGB + " 其他货币抓取靠猜 {},taskkey {}", currency,context.get(Constants.LUA_TASK_KEY));
                    }
                    var cardNumbers = null;
                    cardNumbers = cardNumber.split(" ");
                    var last4No = "";
                    for each (var cardNo in cardNumbers) {
                        if("".equals(last4No)){
                            last4No = getLast4Str(cardNo);
                        }else{
                            last4No = last4No+","+getLast4Str(cardNo);
                        }
                    }
                    logger.info("任务taskKey = {}, last4No = {}", context.get(LUA_TASK_KEY), last4No);
                    logger.info("任务taskKey = {}, last4No.split = {}", context.get(LUA_TASK_KEY), last4No.split);
                    infos.put(last4No.split(","), creditBill);
                    accountInfoFlag = true;
                }
                continue;
            }
            if (text.contains("上期应还总额") && text.contains("本期应还总额") && !text.contains("交易摘要")) {
                var e = element.select("#fixBand4");
                if (e != null) {
                    var trs = e.select("tr");
                    for each (var element2 in trs) {
                        var tds = element2.select("td");
                        if (tds.size() < 5 || tds.text().contains("Card Number")) {
                            continue;
                        }
                        var cardNumber = tds.get(0).text().trim();
                        var cardNumbers = cardNumber.split(" ");
                        var creditBill = null;
                        for each (var billAllData in infos.entrySet()) {
                            for each (var str in billAllData.getKey()) {
                                for each (var numbers in cardNumbers) {
                                    if(numbers.contains(str)){
                                        creditBill = billAllData.getValue();
                                        break;
                                    }
                                }
                            }
                        }

                        if (creditBill == null) {
                            logger.error(BankCode.CGB + " 详单解析出错,taskkey {}",context.get(Constants.LUA_TASK_KEY));
                            return null;
                        }
                        var currency = tds.get(1).text().trim();
                        // 上期账单金额
                        var last_balance = tds.get(2).text().trim();
                        // 上期还款金额
                        var last_payment = tds.get(6).text().trim();
                        last_payment = "-" + last_payment;
                        // 本期新增款额
                        var new_charges = tds.get(4).text().trim();
                        if (currency.equals("人民币")) {
                            creditBill.setLastBalance(GetJiner(last_balance));
                            //creditBill.setLastPayment(GetJiner(last_payment));
                            creditBill.setNewCharges(GetJiner(new_charges));
                        } else {
                            creditBill.setUsdLastBalance(GetJiner(last_balance));
                            //creditBill.setUsdLastPayment(GetJiner(last_payment));
                            creditBill.setUsdNewCharges(GetJiner(new_charges));
                            logger.error(BankCode.CGB + " 其他货币抓取靠猜 {},taskkey {}", currency,context.get(Constants.LUA_TASK_KEY));
                        }
                    }
                }
            }
        }
    }
    if (!accountInfoFlag) {// 没有解析到账单周期
        logger.error(BankCode.CGB + " 么有解析到账户信息,taskkey {}",context.get(Constants.LUA_TASK_KEY));
        return null;
    }
    var loopBand1 = doc.select("#loopBand1");
    if (loopBand1.size() >= 2) {
        logger.info(BankCode.CGB + " 和详单同级表格个数为 {},taskkey {}", loopBand1.size(),context.get(Constants.LUA_TASK_KEY));
        var loopBand2 = loopBand1.get(1).select("#loopBand2");
        for each (var element2 in loopBand2) {
            var cardNumber = element2.select("#groupHeader1").text();
            var card_num = getLast4Str(cardNumber);
            var cardNumbers = cardNumber.split(" ");
            var creditBill = null;
            for each (var billAllData in infos.entrySet()) {
                for each (var str in billAllData.getKey()) {
                    for each (var numbers in cardNumbers) {
                        if(numbers.contains(str)){
                            creditBill = billAllData.getValue();
                            break;
                        }
                    }
                }
            }
            var fixBand7 = element2.select("#fixBand7");
            var bills = new ArrayList();
            if(creditBill!=null){
                creditBill.setShoppingSheets(bills);
                if (fixBand7.size() < 1) {
                    logger.error(BankCode.CGB + " 账单解析不服规则 长度小于1 {},taskkey {}", fixBand7.size(),context.get(Constants.LUA_TASK_KEY));
                    return null;
                }
                var trs1 = fixBand7.select("tr");
                var billId = 0;
                for each (var element3 in trs1) {
                    if (element3.select("td").size() < 5) {
                        continue;
                    }
                    var jiaoyiri = element3.select("td").get(0).text();
                    var ruzhangri = element3.select("td").get(1).text();
                    var zhaiyao = element3.select("td").get(2).text();
                    var jiaoyijiner = element3.select("td").get(3).text();
                    var jiaoyihuobi = element3.select("td").get(4).text();
                    var ruzhangjiner = element3.select("td").get(5).text();
                    if (StringUtils.isBlank(jiaoyiri) || !jiaoyiri.matches("\\d{4}-\\d{2}-\\d{2}")) {
                        continue;
                    }

                    var billdatail = createExpense(++billId, card_num, jiaoyiri, zhaiyao, jiaoyihuobi, jiaoyijiner, ruzhangri, ruzhangjiner);
                    bills.add(billdatail);
                }

                if (isDebug) {
                    System.out.println(JSON.toJSON(creditBill));
                }
            }
        }
    } else {
        logger.error(BankCode.CGB + " 详单解析出错,taskkey {}",context.get(Constants.LUA_TASK_KEY));
    }
    return infos;
}

/**
 * 获取字符串后四位字符
 *
 * @param str
 * @return
 */
function getLast4Str( str) {
    if (str != null && str.length() >= 4) {// 从混淆后的卡号中取出后四位
        return str.substring(str.length() - 4);
    } else {
        return str
    }
}

/**
 * 构造
 *
 * @param id
 * @param card_num
 * @param jiaoyiri
 * @param zhaiyao
 * @param jiaoyihuobi
 * @param jiaoyijiner
 * @param ruzhangri
 * @param ruzhangjiner
 * @return
 */
function createExpense( id,  card_num,  jiaoyiri,  zhaiyao,  jiaoyihuobi,  jiaoyijiner,
                        ruzhangri,  ruzhangjiner) {
    var billdatail = getExpense();
    if (StringUtils.isNotBlank(zhaiyao)) {
        zhaiyao = zhaiyao.replaceAll(" ", "");
    }
    billdatail.setId(UUID.randomUUID().toString());// 账单id
    billdatail.setCardNum(card_num);// 卡号后四位
    billdatail.setPostDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(new Date(MyDateUtil.convergeTime(jiaoyiri)), "yyyy-MM-dd")));// 记账时间
    billdatail.setCategory(CategoryUtil.getCreditCategory("CGB",zhaiyao, jiaoyihuobi));// 交易类型
    billdatail.setOrderIndex(id);
    billdatail.setTransDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(new Date(MyDateUtil.convergeTime(jiaoyiri)))));// 交易日期
    billdatail.setCurrencyType("CNY");// 货比
    billdatail.setAmountMoney(GetJiner(jiaoyijiner));// 交易金额
    // billdatail.setTransAddr("");
    // billdatail.setTransMethod("");
    // billdatail.setTransChannel("");
    billdatail.setDescription(zhaiyao);// 摘要
    // billdatail.setRemark("");
    var o = new Object(jiaoyiri, ruzhangri, jiaoyijiner, jiaoyihuobi, ruzhangjiner, zhaiyao );
    // logger.info("交易日 : {},入账日 : {},交易金额 : {},交易货币 : {},入账金额 : {},户口交易摘要 : {}",
    // o);
    return billdatail;
}

function generateURL( inUrl,  paramsMap) {
    var uri = null;
    try {
        var uriBuilder = new URIBuilder(inUrl);
        if (null != paramsMap) {
            for each (var entry in paramsMap.entrySet()) {
                uriBuilder.addParameter(entry.getKey(), entry.getValue());
            }
        }
        uri = uriBuilder.build();
    } catch ( e) {
        // statCaughtException(context, e);
        logger.error(e);
    }
    var outUrl = uri.toString();
    logger.info("生成的url为  = " + outUrl);
    return outUrl;
}
//金额格式处理
function  GetJiner( jiner) {
    if (jiner == null || jiner.replaceAll("[^\\d]", "").equals("")) {
        return null;
    }

    if (jiner.contains("+")) {
        var jiners = jiner.split(/\+/);
        var d = 0;
        for each (var string in jiners) {
            d = d + GetJiner(string).doubleValue();
        }
        return GetJiner("" + d);
    }
    jiner = jiner.replaceAll("￥", "").trim();
    jiner = jiner.replaceAll("¥", "").trim();
    jiner = jiner.replaceAll("\\s*", "").trim();
    jiner = jiner.trim().equals("") ? "0" : jiner;
    var a = 0;
    jiner = jiner.trim();
    if (jiner.matches(".*?\\.\\d{1,}\u5143")) {
        var newjiner = jiner.replaceAll("(.*?\\.\\d{1,})\u5143", "$1");
        newjiner = newjiner.replaceAll("[^\\d\\.]", "");
        a = Double.parseDouble(newjiner);
    } else if (jiner.matches("\\d{1,}\\.\\d{1,}")) {
        a = Double.parseDouble(jiner);
    } else if (jiner.matches("\\d{1,}")) {
        a = Double.parseDouble(jiner);
    } else if (jiner.matches("(\\+|-)\\d{1,}\\.\\d{1,}")) {
        a = Double.parseDouble(jiner);
    } else if (jiner.matches("(\\+|-)\\d{1,}")) {
        a = Double.parseDouble(jiner);
    } else {
        var newjiner = jiner.replaceAll("[^\\d\\.\\+\\-]", "");
        try {
            a = Double.parseDouble(newjiner);
        } catch (e) {
            // statCaughtException(context, e);
            logger.error("------" + newjiner, e);
        }
    }
    var b = new BigDecimal(a);
    return b.setScale(2, BigDecimal.ROUND_HALF_UP);
}

/**
 * 解析储蓄卡交易记录
 *
 * @param EMP_SID
 * @param map
 * @param creditCardAllData
 */
function crawlerChuXuKaBusiness(EMP_SID, map,  creditCardAllData) {
    var c = Calendar.getInstance();
    var endDate = TimeUtil.getTimeStr(c.getTime(), "yyyyMMdd");
    c.add(Calendar.MONTH, -12);// 查询12个月的数据
    var beginDate = TimeUtil.getTimeStr(c.getTime(), "yyyyMMdd");
    var postdata = new LinkedHashMap();
    postdata.put("cardNo", map.get("accountNo"));
    postdata.put("sasbDepositNo", "");
    postdata.put("currencyType", "99");
    postdata.put("productName", "999");
    postdata.put("cardState", "A");
    postdata.put("pageQueryFlag", "FT");
    postdata.put("isAutoDump", "");
    postdata.put("turnPageBeginPos", "1");
    postdata.put("EMP_SID", EMP_SID);
    postdata.put("submitTimestamp", TimeUtil.getTimeStr(new Date(), "yyyyMMddHHmmssSSS"));
    postdata.put("trxCode", "b010101");
    logger.info(BankCode.CGB + "卡" + card + " 卡信息开始,taskkey {}",context.get(Constants.LUA_TASK_KEY));
    var html = ajax_post("https://ebanks.cgbchina.com.cn/perbank/AC0002.do", postdata);
    storeDataToFile(context, html, card+"_card_"+(card_Id++)+".html");
    parserBalance(html, creditCardAllData);
    logger.info(BankCode.CGB + "卡" + card + " 卡信息结束, taskkey {}",context.get(Constants.LUA_TASK_KEY));
    postdata.clear();
    postdata.put("pageQueryFlag", "FT");
    postdata.put("accNo", map.get("accountNo"));
    postdata.put("currency", "999");
    postdata.put("beginDate", beginDate);
    postdata.put("endDate", endDate);
    postdata.put("transferDirection", "0");
    postdata.put("turnPageShowNum", "10");
    postdata.put("mediumNo", "");
    postdata.put("newBusinessType", "YSV");
    postdata.put("sasbDepositNo", "");
    postdata.put("turnPageBeginPage", "0");
    postdata.put("turnPageTotalNum", "0");
    postdata.put("turnPageCurAccNum", "0");
    postdata.put("EMP_SID", EMP_SID);
    logger.info(BankCode.CGB + "卡" + card + " 账单信息开始,taskkey {}",context.get(Constants.LUA_TASK_KEY));
    html = ajax_post("https://ebanks.cgbchina.com.cn/perbank/AC0003.do", postdata);
    storeDataToFile(context, html,card+"_bill_shopping_sheets_"+(bill_ShoppingSheet_Id++)+".html");
    parserBusiness(html, creditCardAllData, postdata);
    var total = parserBusiness(html, creditCardAllData, postdata);
    for (var i = 2; i <= total; i++) {
        postdata.put("pageQueryFlag", "DN");
        postdata.put("pageQueryFlag4EB", "DN");
        postdata.put("turnPageBeginPage",i);
        html = ajax_post("https://ebanks.cgbchina.com.cn/perbank/AC0003.do", postdata);
        storeDataToFile(context, html,card+"_bill_shopping_sheets_"+(bill_ShoppingSheet_Id++)+".html");
        parserBusiness(html, creditCardAllData, postdata);
    }
    logger.info(BankCode.CGB + " 账单信息成功,taskkey {}",context.get(Constants.LUA_TASK_KEY));
}

/**
 * 解析余额
 *
 * @param html
 * @param creditCardAllData
 */
function parserBalance( html,  creditCardAllData) {
    var balanceMap = JSON.parseObject(html);
    if (balanceMap != null&&balanceMap.get("cd")!="") {
        var cd =  balanceMap.get("cd");
        if (cd != null) {
            var list =  cd.get("iSubHomeAccountList");
            if (list != null) {

                // YSV-活期 YTM-整存整取 YNT-通知存款 ATF-丰收优利 YTD-定活智能通
                for each (var map2 in list) {
                    var newBusinessType = map2.get("newBusinessType") == null ? "" : (map2.get("newBusinessType") + "");
                    var currencyType = map2.get("currencyType") == null ? "" : (map2.get("currencyType") + "");
                    if ("YSV".equals(newBusinessType)) {// 活期
                        var balance = map2.get("balance") == null ? "" : (map2.get("balance") + "");
                        var currency_type = "";
                        if (currencyType.equals("01")) {
                            creditCardAllData.setBalance(moneyChu100(balance));
                        } else {
                            logger.warn("未知币种 {} ", currencyType);
                        }

                        var deposit = getCreditCardTimeDeposit();
                        deposit.setBalance(moneyChu100(balance));
                        deposit.setDepositType("活期储蓄");
                        deposit.setCurrencyType("CNY");
                        if (creditCardAllData.getDeposits() == null) {
                            creditCardAllData.setDeposits(new ArrayList());
                        }
                        creditCardAllData.getDeposits().add(deposit);
                    } else if ("YTM".equals(newBusinessType)) {// 整存整取
                        var balance = map2.get("balance") == null ? "" : (map2.get("balance") + "");
                        var openDate = map2.get("openDate") == null ? "" : (map2.get("openDate") + "");
                        var interestEndDate = map2.get("interestEndDate") == null ? "" : (map2.get("interestEndDate") + "");
                        var savingPeriod = map2.get("savingPeriod") == null ? "" : (map2.get("savingPeriod") + "");
                        var termDepositRate = map2.get("termDepositRate") == null ? "" : (map2.get("termDepositRate") + "");
                        var currency_type = "";
                        if (currencyType.equals("01")) {
                            currency_type = "CNY";
                        } else {
                            logger.warn("未知币种 {} ", currencyType);
                        }
                        var realyPeriod = savePeroid.get(savingPeriod);

                        var money = GetJiner(termDepositRate);
                        var d = money.doubleValue() / 100000000;

                        var deposit = getCreditCardTimeDeposit();
                        deposit.setBalance(moneyChu100(balance));
                        deposit.setDepositType("整存整取");
                        deposit.setCurrencyType("CNY");
                        deposit.setDepositDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(new Date(MyDateUtil.convergeTime(openDate)), "yyyy-MM-dd")));
                        deposit.setDueDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(new Date(MyDateUtil.convergeTime(interestEndDate)), "yyyy-MM-dd")));
                        deposit.setInterest(GetJiner(d + ""));
                        if (StringUtils.isNotBlank(realyPeriod)) {
                            var periodStr = realyPeriod.split("-")[0];
                            deposit.setPeriod(Integer.parseInt(periodStr));
                            deposit.setPeriodUnit(realyPeriod.split("-")[1]);
                        }
                        if (creditCardAllData.getDeposits() == null) {
                            creditCardAllData.setDeposits(new ArrayList());
                        }
                        creditCardAllData.getDeposits().add(deposit);
                    } else if ("".equals(newBusinessType)) {
                        logger.error("其他存款类型没有解析");
                    }
                }
                return;
            }
        }
    }
    logger.error("解析余额信息出错");
}

/**
 * 解析交易记录
 *
 * @param html
 * @param creditCardAllData
 * @param postdata
 */
function parserBusiness( html,  creditCardAllData,  postdata) {
    var total = 0;
    var balanceMap = JSON.parseObject(html);
    if (balanceMap != null) {
        var cd =  balanceMap.get("cd");
        if (cd != null&&cd !="") {
            var turnPageTotalPage =  cd.get("turnPageTotalPage");
            var turnPageTotalNum = cd.get("turnPageTotalNum");
            var turnPageCurAccNum =  cd.get("turnPageCurAccNum");
            var lastRecord =  cd.get("lastRecord");
            if (StringUtils.isNotBlank(turnPageTotalPage) && turnPageTotalPage.matches("\\d{1,}")) {
                total = Integer.parseInt(turnPageTotalPage);
                if (postdata != null) {
                    postdata.put("lastRecord", lastRecord);
                    postdata.put("turnPageTotalNum", turnPageTotalNum);
                    postdata.put("turnPageCurAccNum", turnPageCurAccNum);
                }
            }
            var iTransferDetailList =  cd.get("iTransferDetailList");
            if (iTransferDetailList != null) {
                // 在卡信息中取得账单信息
                var list = creditCardAllData.getBills();
                var billMap = new LinkedHashMap();
                if (list == null) {// 如果账单信息为空，那么重新创建一个
                    list = new ArrayList();
                    creditCardAllData.setBills(list);
                }
                // 将所有账单信息添加到月份与账单的映射中
                for each (var billAllData in list) {
                    billMap.put(billAllData.getBillMonth(), billAllData);
                }
                for each (var map2 in iTransferDetailList) {
                    var billdatail = getExpense();
                    var transDate =  map2.get("transDate");// 交易时间
                    var channelType =  map2.get("channelType");// 交易渠道
                    // String recordDate =
                    // map2.get("recordDate");// 记录时间
                    var transTime =  map2.get("transTime");// 交易时间
                    var currencyType =  map2.get("currencyType");// 货币
                    var opponencyAccount =  map2.get("opponencyAccount");// 对方账号
                    var opponencyAcctName =  map2.get("opponencyAcctName");// 对方姓名
                    var usableBalance =  map2.get("usableBalance");// 余额
                    var transferAmt =  map2.get("transferAmt");// 交易金额
                    var handAmount =  map2.get("handAmount");// 描述
                    var noteMsg =  map2.get("noteMsg");// 备注（转账人手填内容）
                    // 交易类型，在js中看C是+ D是- 不一定对
                    var transferType =  map2.get("transferType");

                    // 交易类型，在js中看C是转入 D是转出 不一定对
                    if (transferType.equals("C")) {
                        transferAmt = "-" + transferAmt;
                    }
                    billdatail.setId(UUID.randomUUID().toString());// 账单id
                    billdatail.setAmountMoney(moneyChu100(transferAmt));
                    billdatail.setBalance(moneyChu100(usableBalance));
                    billdatail.setCardNum(creditCardAllData.getCardNum());
                    // 消费类型(WITHDRAW-取现;PAYMENTS-还款：INTEREST-预期利息:OVERDUEPAYMENT-延滞金：
                    // OVERDUEFEE-超额费:INSTALLMENT.分期：
                    // SHOPPING-消费：OTHERFEE-其他费用）
                    var type = CategoryUtil.getDebitCategory(handAmount, billdatail.getAmountMoney().toString());
                    if (StringUtils.isBlank(type)) {
                        var a = "";
                        if (transferType.equals("C")) {
                            a = "其它收入";
                        } else {
                            a = "其它支出";
                        }
                        type = types.get(a);
                    }
                    billdatail.setCategory(type);
                    if (currencyType != null && currencyType.equals("156")) {
                        billdatail.setCurrencyType(CreditResultUtil.convertCurr("人民币"));// 货比
                    }
                    billdatail.setDescription(handAmount);
                    billdatail.setNameOnOppositeCard(opponencyAcctName);
                    // e.setOppositeBank("");
                    billdatail.setOppositeCardNo(opponencyAccount);
                    var postDate = new Date(MyDateUtil.convergeTime(transDate));
                    billdatail.setPostDate(yyyy_MM_dd_PARSER.parse(TimeUtil.getTimeStr(postDate, "yyyy-MM-dd")));
                    billdatail.setRemark(noteMsg);
                    // e.setTransAddr("");
                    billdatail.setTransChannel(channelType);
                    billdatail.setOrderIndex( ++chuxukaId);
                    billdatail.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(yyyy_MM_dd_PARSER.format(billdatail.getPostDate()) + " " + transTime.replaceAll("(\\d{2})(\\d{2})(\\d{2})", "$1:$2:$3")));
                    // e.setTransMethod("");
                    var bill_month = TimeUtil.getTimeStr(postDate, "yyyy-MM");
                    // 在映射中取得账单
                    var billAllData = billMap.get(bill_month);
                    if (billAllData == null) {// 如果账单为空，那么新构造一个
                        billAllData = getBillAllData();
                        billAllData.setBillMonth(bill_month);
                        billAllData.setBillDate(yyyy_MM_dd_PARSER.parse(getBillDate(bill_month)));
                        billAllData.setBillId(UUID.randomUUID().toString());
                        billAllData.setBillType("");
                        billAllData.setBankName("广发银行");
                        // 将构造的放到映射中
                        billMap.put(bill_month, billAllData);
                    }
                    // 在账单中取得详单
                    var expenseList = billAllData.getShoppingSheets();
                    if (expenseList == null) {// 如果详单为空，那么构造
                        expenseList = new ArrayList();
                        // 将构造的详单放到账单中
                        billAllData.setShoppingSheets(expenseList);
                    }
                    // 将当前记录放到详单中
                    expenseList.add(billdatail);
                }
                // 重新初始化所有账单列表
                if (billMap.size() > 0) {
                    creditCardAllData.getBills().clear();
                    creditCardAllData.setBills(new ArrayList(billMap.values()));
                }
                return total;
            }
        }
    }
    logger.error("解析余额信息出错,taskkey {}",context.get(Constants.LUA_TASK_KEY));
    return total;
}

function getBillDate( bill_month) {
    if(bill_month!=null){
        bill_month = bill_month+"-01";
    }
    return bill_month;
}

/**
 * 将金额除100
 *
 * @param moneyStr
 * @return
 */
function moneyChu100( moneyStr) {
    var money = GetJiner(moneyStr);
    var d = money.doubleValue() / 100;
    return GetJiner(d + "");
}

function nextCard() {
    card++;
    card_Id = 1;
    bill_ShoppingSheet_Id = 1;
    bill_ID = 1;
}

function getCreditCardAllData(){
    var creditCardAllData = new CreditCardAllData();
    creditCardAllData.setBalance(null);
    creditCardAllData.setCashBalance(null);
    creditCardAllData.setCashLimit(null);
    creditCardAllData.setCreditLimit(null);
    return creditCardAllData;
}

function getCreditCardTimeDeposit(){
    var creditCardTimeDeposit = new CreditCardTimeDeposit();
    creditCardTimeDeposit.setBalance(null);
    creditCardTimeDeposit.setInterest(null);
    creditCardTimeDeposit.setPeriod(null);
    return creditCardTimeDeposit;

}

function getBillAllData(){
    var billAllData = new BillAllData();
    billAllData.setCashLimit(null);
    billAllData.setCreditLimit(null);
    billAllData.setInterest(null);
    billAllData.setLastBalance(null);
    billAllData.setLastPayment(null);
    billAllData.setMinPayment(null);
    billAllData.setNewBalance(null);
    billAllData.setNewCharges(null);
    billAllData.setUsdCashLimit(null);
    billAllData.setUsdCreditLimit(null);
    billAllData.setUsdInterest(null);
    billAllData.setUsdLastBalance(null);
    billAllData.setUsdLastPayment(null);
    billAllData.setUsdMinPayment(null);
    billAllData.setUsdNewBalance(null);
    billAllData.setUsdNewCharges(null);
    return billAllData;
}

function getExpense(){
    var expense = new Expense();
    expense.setAmountMoney(null);
    expense.setBalance(null);
    return expense;
}

function getInstallment(){
    var installment = new Installment();
    installment.setAmountMoney(null);
    installment.setHandingFee(null);
    installment.setTransferFee(null);
    return installment;
}

function test(creditCardAllData){
    var billmap = new HashMap();
    var list = new ArrayList();
    billmap = getBillMap("201801",creditCardAllData,"12345678912346578",new Date());

    var billData = null;
    System.out.println(billmap.entrySet().size());
    for each (var billAllData in billmap.entrySet()) {
        System.out.println(billAllData.getKey().length);
        // System.out.println(billAllData.getKey());
        for each(var str in billAllData.getKey()) {
            System.out.println(str);
            if("12345678912346578".contains(str)){
                billData = billAllData.getValue();
                System.out.print(billData);
            }
        }
    }
    list.add(billData);

}

/**
 * 截取当前屏幕的状态
 * @return
 */
function getScreenShots() {
    var map=new LinkedHashMap();
    map.put("method", "getScreenShots");
    return sendAndReceive(map);
}

/**
 * 获取文本内容
 */
function getInnerHTML(id){
    var map=new LinkedHashMap();
    map.put("method", "getInnerHTML");
    map.put("id",id);
    return sendAndReceive(map);
}